﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using Helpers;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.CharacterDevelopment;
using TaleWorlds.CampaignSystem.ComponentInterfaces;
using TaleWorlds.CampaignSystem.MapEvents;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.CampaignSystem.Party.PartyComponents;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.CampaignSystem.Settlements.Buildings;
using TaleWorlds.CampaignSystem.Settlements.Workshops;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.ObjectSystem;
using TaleWorlds.SaveSystem;

namespace TaleWorlds.CampaignSystem.Settlements
{
	// Token: 0x0200035E RID: 862
	public class Town : Fief
	{
		// Token: 0x060031EF RID: 12783 RVA: 0x000D1065 File Offset: 0x000CF265
		internal static void AutoGeneratedStaticCollectObjectsTown(object o, List<object> collectedObjects)
		{
			((Town)o).AutoGeneratedInstanceCollectObjects(collectedObjects);
		}

		// Token: 0x060031F0 RID: 12784 RVA: 0x000D1074 File Offset: 0x000CF274
		protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
		{
			base.AutoGeneratedInstanceCollectObjects(collectedObjects);
			collectedObjects.Add(this.Buildings);
			collectedObjects.Add(this.BuildingsInProgress);
			collectedObjects.Add(this._ownerClan);
			collectedObjects.Add(this._marketData);
			collectedObjects.Add(this._governor);
			collectedObjects.Add(this._soldItems);
			collectedObjects.Add(this.Workshops);
			collectedObjects.Add(this.LastCapturedBy);
		}

		// Token: 0x060031F1 RID: 12785 RVA: 0x000D10E8 File Offset: 0x000CF2E8
		internal static object AutoGeneratedGetMemberValueWorkshops(object o)
		{
			return ((Town)o).Workshops;
		}

		// Token: 0x060031F2 RID: 12786 RVA: 0x000D10F5 File Offset: 0x000CF2F5
		internal static object AutoGeneratedGetMemberValueLastCapturedBy(object o)
		{
			return ((Town)o).LastCapturedBy;
		}

		// Token: 0x060031F3 RID: 12787 RVA: 0x000D1102 File Offset: 0x000CF302
		internal static object AutoGeneratedGetMemberValueGarrisonAutoRecruitmentIsEnabled(object o)
		{
			return ((Town)o).GarrisonAutoRecruitmentIsEnabled;
		}

		// Token: 0x060031F4 RID: 12788 RVA: 0x000D1114 File Offset: 0x000CF314
		internal static object AutoGeneratedGetMemberValueBuildings(object o)
		{
			return ((Town)o).Buildings;
		}

		// Token: 0x060031F5 RID: 12789 RVA: 0x000D1121 File Offset: 0x000CF321
		internal static object AutoGeneratedGetMemberValueBuildingsInProgress(object o)
		{
			return ((Town)o).BuildingsInProgress;
		}

		// Token: 0x060031F6 RID: 12790 RVA: 0x000D112E File Offset: 0x000CF32E
		internal static object AutoGeneratedGetMemberValueBoostBuildingProcess(object o)
		{
			return ((Town)o).BoostBuildingProcess;
		}

		// Token: 0x060031F7 RID: 12791 RVA: 0x000D1140 File Offset: 0x000CF340
		internal static object AutoGeneratedGetMemberValueInRebelliousState(object o)
		{
			return ((Town)o).InRebelliousState;
		}

		// Token: 0x060031F8 RID: 12792 RVA: 0x000D1152 File Offset: 0x000CF352
		internal static object AutoGeneratedGetMemberValue_prosperity(object o)
		{
			return ((Town)o)._prosperity;
		}

		// Token: 0x060031F9 RID: 12793 RVA: 0x000D1164 File Offset: 0x000CF364
		internal static object AutoGeneratedGetMemberValue_wallLevel(object o)
		{
			return ((Town)o)._wallLevel;
		}

		// Token: 0x060031FA RID: 12794 RVA: 0x000D1176 File Offset: 0x000CF376
		internal static object AutoGeneratedGetMemberValue_ownerClan(object o)
		{
			return ((Town)o)._ownerClan;
		}

		// Token: 0x060031FB RID: 12795 RVA: 0x000D1183 File Offset: 0x000CF383
		internal static object AutoGeneratedGetMemberValue_security(object o)
		{
			return ((Town)o)._security;
		}

		// Token: 0x060031FC RID: 12796 RVA: 0x000D1195 File Offset: 0x000CF395
		internal static object AutoGeneratedGetMemberValue_loyalty(object o)
		{
			return ((Town)o)._loyalty;
		}

		// Token: 0x060031FD RID: 12797 RVA: 0x000D11A7 File Offset: 0x000CF3A7
		internal static object AutoGeneratedGetMemberValue_marketData(object o)
		{
			return ((Town)o)._marketData;
		}

		// Token: 0x060031FE RID: 12798 RVA: 0x000D11B4 File Offset: 0x000CF3B4
		internal static object AutoGeneratedGetMemberValue_tradeTax(object o)
		{
			return ((Town)o)._tradeTax;
		}

		// Token: 0x060031FF RID: 12799 RVA: 0x000D11C6 File Offset: 0x000CF3C6
		internal static object AutoGeneratedGetMemberValue_governor(object o)
		{
			return ((Town)o)._governor;
		}

		// Token: 0x06003200 RID: 12800 RVA: 0x000D11D3 File Offset: 0x000CF3D3
		internal static object AutoGeneratedGetMemberValue_soldItems(object o)
		{
			return ((Town)o)._soldItems;
		}

		// Token: 0x17000C0F RID: 3087
		// (get) Token: 0x06003201 RID: 12801 RVA: 0x000D11E0 File Offset: 0x000CF3E0
		// (set) Token: 0x06003202 RID: 12802 RVA: 0x000D11E8 File Offset: 0x000CF3E8
		public float Prosperity
		{
			get
			{
				return this._prosperity;
			}
			set
			{
				this._prosperity = value;
				if (this._prosperity < 0f)
				{
					this._prosperity = 0f;
				}
			}
		}

		// Token: 0x06003203 RID: 12803 RVA: 0x000D1209 File Offset: 0x000CF409
		public IEnumerable<PartyBase> GetDefenderParties(MapEvent.BattleTypes battleType)
		{
			yield return base.Settlement.Party;
			foreach (MobileParty mobileParty in base.Settlement.Parties)
			{
				if (mobileParty.MapFaction.IsAtWarWith(base.Settlement.SiegeEvent.BesiegerCamp.LeaderParty.MapFaction) && mobileParty.IsActive && !mobileParty.IsVillager && !mobileParty.IsCaravan && (!mobileParty.IsMilitia || (!this.InRebelliousState && battleType != MapEvent.BattleTypes.SallyOut)))
				{
					yield return mobileParty.Party;
				}
			}
			List<MobileParty>.Enumerator enumerator = default(List<MobileParty>.Enumerator);
			yield break;
			yield break;
		}

		// Token: 0x06003204 RID: 12804 RVA: 0x000D1220 File Offset: 0x000CF420
		public PartyBase GetNextDefenderParty(ref int partyIndex, MapEvent.BattleTypes battleType)
		{
			partyIndex++;
			if (partyIndex == 0)
			{
				return base.Settlement.Party;
			}
			for (int i = partyIndex - 1; i < base.Settlement.Parties.Count; i++)
			{
				MobileParty mobileParty = base.Settlement.Parties[i];
				if (mobileParty.MapFaction.IsAtWarWith(base.Settlement.SiegeEvent.BesiegerCamp.LeaderParty.MapFaction) && mobileParty.IsActive && !mobileParty.IsVillager && !mobileParty.IsCaravan && (!mobileParty.IsMilitia || (!this.InRebelliousState && battleType != MapEvent.BattleTypes.SallyOut)))
				{
					partyIndex = i + 1;
					return mobileParty.Party;
				}
			}
			return null;
		}

		// Token: 0x17000C10 RID: 3088
		// (get) Token: 0x06003205 RID: 12805 RVA: 0x000D12D6 File Offset: 0x000CF4D6
		public CultureObject Culture
		{
			get
			{
				return base.Owner.Settlement.Culture;
			}
		}

		// Token: 0x17000C11 RID: 3089
		// (get) Token: 0x06003206 RID: 12806 RVA: 0x000D12E8 File Offset: 0x000CF4E8
		public float ProsperityChange
		{
			get
			{
				return Campaign.Current.Models.SettlementProsperityModel.CalculateProsperityChange(this, false).ResultNumber;
			}
		}

		// Token: 0x17000C12 RID: 3090
		// (get) Token: 0x06003207 RID: 12807 RVA: 0x000D1313 File Offset: 0x000CF513
		public ExplainedNumber ProsperityChangeExplanation
		{
			get
			{
				return Campaign.Current.Models.SettlementProsperityModel.CalculateProsperityChange(this, true);
			}
		}

		// Token: 0x17000C13 RID: 3091
		// (get) Token: 0x06003208 RID: 12808 RVA: 0x000D132C File Offset: 0x000CF52C
		public int GarrisonChange
		{
			get
			{
				return (int)Campaign.Current.Models.SettlementGarrisonModel.CalculateGarrisonChange(base.Owner.Settlement, false).ResultNumber;
			}
		}

		// Token: 0x17000C14 RID: 3092
		// (get) Token: 0x06003209 RID: 12809 RVA: 0x000D1364 File Offset: 0x000CF564
		public int GarrisonChangeAutoRecruitment
		{
			get
			{
				return (int)Campaign.Current.Models.SettlementGarrisonModel.CalculateGarrisonChangeAutoRecruitment(base.Owner.Settlement, false).ResultNumber;
			}
		}

		// Token: 0x17000C15 RID: 3093
		// (get) Token: 0x0600320A RID: 12810 RVA: 0x000D139A File Offset: 0x000CF59A
		public ExplainedNumber GarrisonChangeExplanation
		{
			get
			{
				return Campaign.Current.Models.SettlementGarrisonModel.CalculateGarrisonChange(base.Owner.Settlement, true);
			}
		}

		// Token: 0x17000C16 RID: 3094
		// (get) Token: 0x0600320B RID: 12811 RVA: 0x000D13BC File Offset: 0x000CF5BC
		public float FoodChange
		{
			get
			{
				return Campaign.Current.Models.SettlementFoodModel.CalculateTownFoodStocksChange(this, true, false).ResultNumber;
			}
		}

		// Token: 0x17000C17 RID: 3095
		// (get) Token: 0x0600320C RID: 12812 RVA: 0x000D13E8 File Offset: 0x000CF5E8
		public float FoodChangeWithoutMarketStocks
		{
			get
			{
				return Campaign.Current.Models.SettlementFoodModel.CalculateTownFoodStocksChange(this, false, false).ResultNumber;
			}
		}

		// Token: 0x17000C18 RID: 3096
		// (get) Token: 0x0600320D RID: 12813 RVA: 0x000D1414 File Offset: 0x000CF614
		public ExplainedNumber FoodChangeExplanation
		{
			get
			{
				return Campaign.Current.Models.SettlementFoodModel.CalculateTownFoodStocksChange(this, true, true);
			}
		}

		// Token: 0x17000C19 RID: 3097
		// (get) Token: 0x0600320E RID: 12814 RVA: 0x000D1430 File Offset: 0x000CF630
		public float LoyaltyChange
		{
			get
			{
				return Campaign.Current.Models.SettlementLoyaltyModel.CalculateLoyaltyChange(this, false).ResultNumber;
			}
		}

		// Token: 0x17000C1A RID: 3098
		// (get) Token: 0x0600320F RID: 12815 RVA: 0x000D145B File Offset: 0x000CF65B
		public ExplainedNumber LoyaltyChangeExplanation
		{
			get
			{
				return Campaign.Current.Models.SettlementLoyaltyModel.CalculateLoyaltyChange(this, true);
			}
		}

		// Token: 0x17000C1B RID: 3099
		// (get) Token: 0x06003210 RID: 12816 RVA: 0x000D1474 File Offset: 0x000CF674
		public float SecurityChange
		{
			get
			{
				return Campaign.Current.Models.SettlementSecurityModel.CalculateSecurityChange(this, false).ResultNumber;
			}
		}

		// Token: 0x17000C1C RID: 3100
		// (get) Token: 0x06003211 RID: 12817 RVA: 0x000D149F File Offset: 0x000CF69F
		public ExplainedNumber SecurityChangeExplanation
		{
			get
			{
				return Campaign.Current.Models.SettlementSecurityModel.CalculateSecurityChange(this, true);
			}
		}

		// Token: 0x17000C1D RID: 3101
		// (get) Token: 0x06003212 RID: 12818 RVA: 0x000D14B8 File Offset: 0x000CF6B8
		public float MilitiaChange
		{
			get
			{
				return Campaign.Current.Models.SettlementMilitiaModel.CalculateMilitiaChange(base.Owner.Settlement, false).ResultNumber;
			}
		}

		// Token: 0x17000C1E RID: 3102
		// (get) Token: 0x06003213 RID: 12819 RVA: 0x000D14ED File Offset: 0x000CF6ED
		public ExplainedNumber MilitiaChangeExplanation
		{
			get
			{
				return Campaign.Current.Models.SettlementMilitiaModel.CalculateMilitiaChange(base.Owner.Settlement, true);
			}
		}

		// Token: 0x17000C1F RID: 3103
		// (get) Token: 0x06003214 RID: 12820 RVA: 0x000D1510 File Offset: 0x000CF710
		public float Construction
		{
			get
			{
				return Campaign.Current.Models.BuildingConstructionModel.CalculateDailyConstructionPower(this, false).ResultNumber;
			}
		}

		// Token: 0x17000C20 RID: 3104
		// (get) Token: 0x06003215 RID: 12821 RVA: 0x000D153B File Offset: 0x000CF73B
		public ExplainedNumber ConstructionExplanation
		{
			get
			{
				return Campaign.Current.Models.BuildingConstructionModel.CalculateDailyConstructionPower(this, true);
			}
		}

		// Token: 0x17000C21 RID: 3105
		// (get) Token: 0x06003216 RID: 12822 RVA: 0x000D1553 File Offset: 0x000CF753
		// (set) Token: 0x06003217 RID: 12823 RVA: 0x000D155B File Offset: 0x000CF75B
		public Clan OwnerClan
		{
			get
			{
				return this._ownerClan;
			}
			set
			{
				if (this._ownerClan != value)
				{
					this.ChangeClanInternal(value);
				}
			}
		}

		// Token: 0x17000C22 RID: 3106
		// (get) Token: 0x06003218 RID: 12824 RVA: 0x000D156D File Offset: 0x000CF76D
		// (set) Token: 0x06003219 RID: 12825 RVA: 0x000D1575 File Offset: 0x000CF775
		public float Security
		{
			get
			{
				return this._security;
			}
			set
			{
				this._security = value;
				if (this._security < 0f)
				{
					this._security = 0f;
					return;
				}
				if (this._security > 100f)
				{
					this._security = 100f;
				}
			}
		}

		// Token: 0x17000C23 RID: 3107
		// (get) Token: 0x0600321A RID: 12826 RVA: 0x000D15AF File Offset: 0x000CF7AF
		// (set) Token: 0x0600321B RID: 12827 RVA: 0x000D15B7 File Offset: 0x000CF7B7
		public float Loyalty
		{
			get
			{
				return this._loyalty;
			}
			set
			{
				this._loyalty = value;
				if (this._loyalty < 0f)
				{
					this._loyalty = 0f;
					return;
				}
				if (this._loyalty > 100f)
				{
					this._loyalty = 100f;
				}
			}
		}

		// Token: 0x17000C24 RID: 3108
		// (get) Token: 0x0600321C RID: 12828 RVA: 0x000D15F1 File Offset: 0x000CF7F1
		public MBReadOnlyList<Village> TradeBoundVillages
		{
			get
			{
				return this._tradeBoundVillagesCache;
			}
		}

		// Token: 0x0600321D RID: 12829 RVA: 0x000D15F9 File Offset: 0x000CF7F9
		internal void SetTradeBoundVillageInternal(Village village)
		{
			this._tradeBoundVillagesCache.Add(village);
		}

		// Token: 0x0600321E RID: 12830 RVA: 0x000D1607 File Offset: 0x000CF807
		internal void RemoveTradeBoundVillageInternal(Village village)
		{
			this._tradeBoundVillagesCache.Remove(village);
		}

		// Token: 0x0600321F RID: 12831 RVA: 0x000D1618 File Offset: 0x000CF818
		public int FoodStocksUpperLimit()
		{
			return (int)((float)(Campaign.Current.Models.SettlementFoodModel.FoodStocksUpperLimit + (this.IsCastle ? Campaign.Current.Models.SettlementFoodModel.CastleFoodStockUpperLimitBonus : 0)) + this.GetEffectOfBuildings(BuildingEffectEnum.Foodstock));
		}

		// Token: 0x17000C25 RID: 3109
		// (get) Token: 0x06003220 RID: 12832 RVA: 0x000D1664 File Offset: 0x000CF864
		// (set) Token: 0x06003221 RID: 12833 RVA: 0x000D166C File Offset: 0x000CF86C
		[SaveableProperty(1005)]
		public Workshop[] Workshops { get; protected set; }

		// Token: 0x17000C26 RID: 3110
		// (get) Token: 0x06003222 RID: 12834 RVA: 0x000D1675 File Offset: 0x000CF875
		public Building CurrentBuilding
		{
			get
			{
				if (!this.BuildingsInProgress.IsEmpty<Building>())
				{
					return this.BuildingsInProgress.Peek();
				}
				return this.CurrentDefaultBuilding;
			}
		}

		// Token: 0x17000C27 RID: 3111
		// (get) Token: 0x06003223 RID: 12835 RVA: 0x000D1696 File Offset: 0x000CF896
		public Building CurrentDefaultBuilding
		{
			get
			{
				return this.Buildings.Find((Building k) => k.IsCurrentlyDefault);
			}
		}

		// Token: 0x17000C28 RID: 3112
		// (get) Token: 0x06003224 RID: 12836 RVA: 0x000D16C2 File Offset: 0x000CF8C2
		public TownMarketData MarketData
		{
			get
			{
				return this._marketData;
			}
		}

		// Token: 0x17000C29 RID: 3113
		// (get) Token: 0x06003225 RID: 12837 RVA: 0x000D16CA File Offset: 0x000CF8CA
		// (set) Token: 0x06003226 RID: 12838 RVA: 0x000D16D2 File Offset: 0x000CF8D2
		public int TradeTaxAccumulated
		{
			get
			{
				return this._tradeTax;
			}
			set
			{
				this._tradeTax = value;
			}
		}

		// Token: 0x17000C2A RID: 3114
		// (get) Token: 0x06003227 RID: 12839 RVA: 0x000D16DB File Offset: 0x000CF8DB
		// (set) Token: 0x06003228 RID: 12840 RVA: 0x000D16E3 File Offset: 0x000CF8E3
		public Hero Governor
		{
			get
			{
				return this._governor;
			}
			set
			{
				if (this._governor != value)
				{
					if (this._governor != null)
					{
						this._governor.GovernorOf = null;
					}
					this._governor = value;
					if (this._governor != null)
					{
						this._governor.GovernorOf = this;
					}
				}
			}
		}

		// Token: 0x06003229 RID: 12841 RVA: 0x000D1720 File Offset: 0x000CF920
		public Town()
		{
			this.Buildings = new MBList<Building>();
			this.BuildingsInProgress = new Queue<Building>();
			this.Workshops = new Workshop[0];
			this._marketData = new TownMarketData(this);
			this._tradeBoundVillagesCache = new MBList<Village>();
		}

		// Token: 0x17000C2B RID: 3115
		// (get) Token: 0x0600322A RID: 12842 RVA: 0x000D177F File Offset: 0x000CF97F
		public static IEnumerable<Town> AllFiefs
		{
			get
			{
				foreach (Town town in Campaign.Current.AllTowns)
				{
					yield return town;
				}
				List<Town>.Enumerator enumerator = default(List<Town>.Enumerator);
				foreach (Town town2 in Campaign.Current.AllCastles)
				{
					yield return town2;
				}
				enumerator = default(List<Town>.Enumerator);
				yield break;
				yield break;
			}
		}

		// Token: 0x17000C2C RID: 3116
		// (get) Token: 0x0600322B RID: 12843 RVA: 0x000D1788 File Offset: 0x000CF988
		public static MBReadOnlyList<Town> AllTowns
		{
			get
			{
				return Campaign.Current.AllTowns;
			}
		}

		// Token: 0x17000C2D RID: 3117
		// (get) Token: 0x0600322C RID: 12844 RVA: 0x000D1794 File Offset: 0x000CF994
		public static MBReadOnlyList<Town> AllCastles
		{
			get
			{
				return Campaign.Current.AllCastles;
			}
		}

		// Token: 0x17000C2E RID: 3118
		// (get) Token: 0x0600322D RID: 12845 RVA: 0x000D17A0 File Offset: 0x000CF9A0
		public override bool IsTown
		{
			get
			{
				return !this._isCastle;
			}
		}

		// Token: 0x17000C2F RID: 3119
		// (get) Token: 0x0600322E RID: 12846 RVA: 0x000D17AB File Offset: 0x000CF9AB
		public override bool IsCastle
		{
			get
			{
				return this._isCastle;
			}
		}

		// Token: 0x0600322F RID: 12847 RVA: 0x000D17B4 File Offset: 0x000CF9B4
		public override void OnInit()
		{
			this.Loyalty = (float)base.Owner.RandomIntWithSeed(1337U, 30, 70);
			this.Security = (float)base.Owner.RandomIntWithSeed(1001U, 40, 60);
			this.TradeTaxAccumulated = (this.IsTown ? (1000 + MBRandom.RandomInt(1000)) : 0);
			base.ChangeGold(20000);
			this.Buildings.Add(new Building(this.IsTown ? DefaultBuildingTypes.Fortifications : DefaultBuildingTypes.Wall, this, 0f, this._wallLevel));
		}

		// Token: 0x06003230 RID: 12848 RVA: 0x000D1854 File Offset: 0x000CFA54
		public void InitializeWorkshops(int count)
		{
			if (count > 0)
			{
				this.Workshops = new Workshop[count];
				for (int i = 0; i < count; i++)
				{
					this.Workshops[i] = new Workshop(base.Owner.Settlement, "workshop_" + i);
				}
			}
		}

		// Token: 0x06003231 RID: 12849 RVA: 0x000D18A5 File Offset: 0x000CFAA5
		[LoadInitializationCallback]
		private void OnLoad()
		{
			this._tradeBoundVillagesCache = new MBList<Village>();
		}

		// Token: 0x06003232 RID: 12850 RVA: 0x000D18B2 File Offset: 0x000CFAB2
		protected override void PreAfterLoad()
		{
			Clan ownerClan = this._ownerClan;
			if (ownerClan == null)
			{
				return;
			}
			ownerClan.OnFortificationAdded(this);
		}

		// Token: 0x06003233 RID: 12851 RVA: 0x000D18C8 File Offset: 0x000CFAC8
		protected override void AfterLoad()
		{
			Workshop[] workshops = this.Workshops;
			for (int i = 0; i < workshops.Length; i++)
			{
				workshops[i].AfterLoad();
			}
			bool flag = false;
			for (int j = this.Buildings.Count - 1; j >= 0; j--)
			{
				Building building = this.Buildings[j];
				if (building.BuildingType == null || !building.BuildingType.IsReady)
				{
					this.Buildings.RemoveAt(j);
					flag = true;
				}
			}
			if (!flag)
			{
				foreach (Building building2 in this.BuildingsInProgress)
				{
					if (building2.BuildingType == null || !building2.BuildingType.IsReady)
					{
						flag = true;
						break;
					}
				}
			}
			if (flag)
			{
				this.BuildingsInProgress.Clear();
			}
			if (this.Governor != null && this.Governor.GovernorOf == null)
			{
				this.Governor = null;
			}
		}

		// Token: 0x17000C30 RID: 3120
		// (get) Token: 0x06003234 RID: 12852 RVA: 0x000D19C8 File Offset: 0x000CFBC8
		public IReadOnlyCollection<Town.SellLog> SoldItems
		{
			get
			{
				return this._soldItems;
			}
		}

		// Token: 0x17000C31 RID: 3121
		// (get) Token: 0x06003235 RID: 12853 RVA: 0x000D19D0 File Offset: 0x000CFBD0
		public IFaction MapFaction
		{
			get
			{
				Clan ownerClan = this.OwnerClan;
				if (ownerClan == null)
				{
					return null;
				}
				return ownerClan.MapFaction;
			}
		}

		// Token: 0x17000C32 RID: 3122
		// (get) Token: 0x06003236 RID: 12854 RVA: 0x000D19E3 File Offset: 0x000CFBE3
		public bool IsUnderSiege
		{
			get
			{
				return base.Settlement.IsUnderSiege;
			}
		}

		// Token: 0x17000C33 RID: 3123
		// (get) Token: 0x06003237 RID: 12855 RVA: 0x000D19F0 File Offset: 0x000CFBF0
		[CachedData]
		public MBReadOnlyList<Village> Villages
		{
			get
			{
				return base.Settlement.BoundVillages;
			}
		}

		// Token: 0x17000C34 RID: 3124
		// (get) Token: 0x06003238 RID: 12856 RVA: 0x000D19FD File Offset: 0x000CFBFD
		// (set) Token: 0x06003239 RID: 12857 RVA: 0x000D1A05 File Offset: 0x000CFC05
		[SaveableProperty(1030)]
		public Clan LastCapturedBy { get; set; }

		// Token: 0x0600323A RID: 12858 RVA: 0x000D1A0E File Offset: 0x000CFC0E
		private void ChangeClanInternal(Clan value)
		{
			if (this._ownerClan != null)
			{
				this.RemoveOwnerClan();
			}
			this._ownerClan = value;
			if (this._ownerClan != null)
			{
				this.SetNewOwnerClan();
			}
		}

		// Token: 0x0600323B RID: 12859 RVA: 0x000D1A34 File Offset: 0x000CFC34
		public float GetEffectOfBuildings(BuildingEffectEnum buildingEffect)
		{
			float num = 0f;
			foreach (Building building in this.Buildings)
			{
				num += building.GetBuildingEffectAmount(buildingEffect);
			}
			return num;
		}

		// Token: 0x0600323C RID: 12860 RVA: 0x000D1A94 File Offset: 0x000CFC94
		private void SetNewOwnerClan()
		{
			this._ownerClan.OnFortificationAdded(this);
			foreach (Village village in base.Settlement.BoundVillages)
			{
				village.Settlement.Party.SetVisualAsDirty();
				VillagerPartyComponent villagerPartyComponent = village.VillagerPartyComponent;
				if (villagerPartyComponent != null)
				{
					villagerPartyComponent.MobileParty.Party.SetVisualAsDirty();
				}
			}
		}

		// Token: 0x0600323D RID: 12861 RVA: 0x000D1B1C File Offset: 0x000CFD1C
		private void RemoveOwnerClan()
		{
			this._ownerClan.OnFortificationRemoved(this);
		}

		// Token: 0x17000C35 RID: 3125
		// (get) Token: 0x0600323E RID: 12862 RVA: 0x000D1B2A File Offset: 0x000CFD2A
		public bool HasTournament
		{
			get
			{
				return this.IsTown && Campaign.Current.TournamentManager.GetTournamentGame(this) != null;
			}
		}

		// Token: 0x0600323F RID: 12863 RVA: 0x000D1B4C File Offset: 0x000CFD4C
		internal void DailyTick()
		{
			this.Loyalty += this.LoyaltyChange;
			this.Security += this.SecurityChange;
			if (base.FoodStocks > 0f)
			{
				base.Owner.OnConsumedFood();
			}
			base.FoodStocks += this.FoodChange;
			if (base.FoodStocks < 0f)
			{
				base.FoodStocks = 0f;
				base.Owner.RemainingFoodPercentage = -100;
			}
			else
			{
				base.Owner.RemainingFoodPercentage = 0;
			}
			if (base.FoodStocks > (float)this.FoodStocksUpperLimit())
			{
				base.FoodStocks = (float)this.FoodStocksUpperLimit();
			}
			if (!this.CurrentBuilding.BuildingType.IsDefaultProject)
			{
				this.TickCurrentBuilding();
			}
			else if (this.Governor != null && this.Governor.GetPerkValue(DefaultPerks.Charm.Virile) && MBRandom.RandomFloat <= DefaultPerks.Charm.Virile.SecondaryBonus)
			{
				Hero randomElement = base.Settlement.Notables.GetRandomElement<Hero>();
				if (randomElement != null)
				{
					ChangeRelationAction.ApplyRelationChangeBetweenHeroes(this.Governor.Clan.Leader, randomElement, 1, false);
				}
			}
			if (this.Governor != null)
			{
				if (this.Governor.GetPerkValue(DefaultPerks.Roguery.WhiteLies) && MBRandom.RandomFloat <= DefaultPerks.Roguery.WhiteLies.SecondaryBonus)
				{
					Hero randomElement2 = base.Settlement.Notables.GetRandomElement<Hero>();
					if (randomElement2 != null)
					{
						ChangeRelationAction.ApplyRelationChangeBetweenHeroes(this.Governor, randomElement2, 1, true);
					}
				}
				if (this.Governor.GetPerkValue(DefaultPerks.Roguery.Scarface) && MBRandom.RandomFloat <= DefaultPerks.Roguery.Scarface.SecondaryBonus)
				{
					Hero randomElementWithPredicate = base.Settlement.Notables.GetRandomElementWithPredicate((Hero x) => x.IsGangLeader);
					if (randomElementWithPredicate != null)
					{
						ChangeRelationAction.ApplyRelationChangeBetweenHeroes(this.Governor, randomElementWithPredicate, 1, true);
					}
				}
			}
			this.Prosperity += this.ProsperityChange;
			this.HandleMilitiaAndGarrisonOfSettlementDaily();
			this.RepairWallsOfSettlementDaily();
		}

		// Token: 0x06003240 RID: 12864 RVA: 0x000D1D40 File Offset: 0x000CFF40
		private void HandleMilitiaAndGarrisonOfSettlementDaily()
		{
			base.Owner.Settlement.Militia += this.MilitiaChange;
			if (this.GarrisonChange >= 1 && base.GarrisonParty == null)
			{
				base.Owner.Settlement.AddGarrisonParty(false);
			}
			if (base.GarrisonParty != null && base.GarrisonParty.IsActive && base.GarrisonParty.MapEvent == null && base.GarrisonParty.CurrentSettlement != null)
			{
				int num = Campaign.Current.Models.DailyTroopXpBonusModel.CalculateDailyTroopXpBonus(this);
				float num2 = Campaign.Current.Models.DailyTroopXpBonusModel.CalculateGarrisonXpBonusMultiplier(this);
				if (num > 0)
				{
					foreach (TroopRosterElement troopRosterElement in base.GarrisonParty.MemberRoster.GetTroopRoster())
					{
						base.GarrisonParty.MemberRoster.AddXpToTroop(MathF.Round((float)num * num2 * (float)troopRosterElement.Number), troopRosterElement.Character);
					}
				}
				this.DailyGarrisonAdjustment();
			}
		}

		// Token: 0x06003241 RID: 12865 RVA: 0x000D1E70 File Offset: 0x000D0070
		private void RepairWallsOfSettlementDaily()
		{
			Settlement settlement = base.Owner.Settlement;
			float maxWallHitPoints = settlement.MaxWallHitPoints;
			if (settlement.SettlementWallSectionHitPointsRatioList.Any((float health) => health < 1f) && !settlement.IsUnderSiege)
			{
				float num = maxWallHitPoints * 0.02f;
				float effectOfBuildings = this.GetEffectOfBuildings(BuildingEffectEnum.WallRepairSpeed);
				if (effectOfBuildings > 0f)
				{
					num += num * effectOfBuildings * 0.01f;
				}
				float num2 = num / settlement.MaxHitPointsOfOneWallSection;
				for (int i = 0; i < settlement.SettlementWallSectionHitPointsRatioList.Count; i++)
				{
					float num3 = settlement.SettlementWallSectionHitPointsRatioList[i];
					float num4 = MathF.Min(1f - num3, num2);
					settlement.SetWallSectionHitPointsRatioAtIndex(i, num3 + num4);
					num2 -= num4;
					if (num2 <= 0f)
					{
						break;
					}
				}
			}
		}

		// Token: 0x06003242 RID: 12866 RVA: 0x000D1F50 File Offset: 0x000D0150
		private void DesertOneTroopFromGarrison()
		{
			if (base.GarrisonParty.MemberRoster.TotalManCount > 0)
			{
				int num = (int)(MBRandom.RandomFloat * (float)base.GarrisonParty.MemberRoster.TotalManCount);
				for (int i = 0; i < base.GarrisonParty.MemberRoster.Count; i++)
				{
					num -= base.GarrisonParty.MemberRoster.GetElementNumber(i);
					if (num < 0)
					{
						TroopRoster troopRoster = TroopRoster.CreateDummyTroopRoster();
						MobilePartyHelper.DesertTroopsFromParty(base.GarrisonParty, i, 1, 0, ref troopRoster);
						return;
					}
				}
			}
		}

		// Token: 0x06003243 RID: 12867 RVA: 0x000D1FD4 File Offset: 0x000D01D4
		private void DailyGarrisonAdjustment()
		{
			int num = base.GarrisonParty.CurrentSettlement.Town.GarrisonChange;
			int num2 = this.GarrisonAutoRecruitmentIsEnabled ? base.GarrisonParty.CurrentSettlement.Town.GarrisonChangeAutoRecruitment : 0;
			num -= num2;
			int limitedPartySize = base.GarrisonParty.LimitedPartySize;
			if (num > 0)
			{
				num = MBMath.ClampInt(num, 0, limitedPartySize - base.GarrisonParty.Party.NumberOfAllMembers - num2);
			}
			if (num < 0)
			{
				for (int i = 0; i < MathF.Abs(num); i++)
				{
					this.DesertOneTroopFromGarrison();
				}
			}
			else if (num > 0)
			{
				base.GarrisonParty.MemberRoster.AddToCounts(base.GarrisonParty.MapFaction.BasicTroop, num, false, 0, 0, true, -1);
			}
			if (num2 > 0)
			{
				int num3 = SettlementHelper.NumberOfVolunteersCanBeRecruitedForGarrison(base.GarrisonParty.CurrentSettlement);
				Hero leader = base.GarrisonParty.CurrentSettlement.OwnerClan.Leader;
				if (num3 > 0)
				{
					float num4 = MBRandom.RandomFloat * (float)num3;
					foreach (Hero hero in base.GarrisonParty.CurrentSettlement.Notables)
					{
						if (num4 <= 0f)
						{
							break;
						}
						int num5 = Campaign.Current.Models.VolunteerModel.MaximumIndexHeroCanRecruitFromHero(leader, hero, -101);
						for (int j = 0; j < num5; j++)
						{
							if (hero.IsAlive && hero.VolunteerTypes[j] != null)
							{
								num4 -= 1f;
								if (num4 <= 0f)
								{
									base.GarrisonParty.MemberRoster.AddToCounts(hero.VolunteerTypes[j], 1, false, 0, 0, true, -1);
									leader.Clan.AutoRecruitmentExpenses += Campaign.Current.Models.PartyWageModel.GetTroopRecruitmentCost(hero.VolunteerTypes[j], leader, false);
									hero.VolunteerTypes[j] = null;
									break;
								}
							}
						}
					}
					if (num4 > 0f)
					{
						foreach (Village village in base.GarrisonParty.CurrentSettlement.BoundVillages)
						{
							if (num4 <= 0f)
							{
								break;
							}
							if (village.VillageState == Village.VillageStates.Normal)
							{
								foreach (Hero hero2 in village.Settlement.Notables)
								{
									if (num4 <= 0f)
									{
										break;
									}
									int num6 = Campaign.Current.Models.VolunteerModel.MaximumIndexHeroCanRecruitFromHero(leader, hero2, -101);
									for (int k = 0; k < num6; k++)
									{
										if (hero2.IsAlive && hero2.VolunteerTypes[k] != null)
										{
											num4 -= 1f;
											if (num4 <= 0f)
											{
												base.GarrisonParty.MemberRoster.AddToCounts(hero2.VolunteerTypes[k], 1, false, 0, 0, true, -1);
												leader.Clan.AutoRecruitmentExpenses += Campaign.Current.Models.PartyWageModel.GetTroopRecruitmentCost(hero2.VolunteerTypes[k], leader, false);
												hero2.VolunteerTypes[k] = null;
												break;
											}
										}
									}
								}
							}
						}
					}
				}
			}
			if (base.GarrisonParty.Party.NumberOfAllMembers > limitedPartySize)
			{
				int num7 = MBRandom.RoundRandomized((float)(base.GarrisonParty.Party.NumberOfAllMembers - limitedPartySize) * 0.2f);
				for (int l = 0; l < num7; l++)
				{
					this.DesertOneTroopFromGarrison();
				}
			}
		}

		// Token: 0x06003244 RID: 12868 RVA: 0x000D23EC File Offset: 0x000D05EC
		public int GetWallLevel()
		{
			int result = 0;
			foreach (Building building in this.Buildings)
			{
				if (building.BuildingType == DefaultBuildingTypes.Fortifications && this.IsTown)
				{
					result = building.CurrentLevel;
					break;
				}
				if (building.BuildingType == DefaultBuildingTypes.Wall && this.IsCastle)
				{
					result = building.CurrentLevel;
					break;
				}
			}
			return result;
		}

		// Token: 0x06003245 RID: 12869 RVA: 0x000D2478 File Offset: 0x000D0678
		public override string ToString()
		{
			return base.Name.ToString();
		}

		// Token: 0x06003246 RID: 12870 RVA: 0x000D2488 File Offset: 0x000D0688
		public override void Deserialize(MBObjectManager objectManager, XmlNode node)
		{
			if (!base.IsInitialized)
			{
				this._wallLevel = ((node.Attributes["level"] != null) ? int.Parse(node.Attributes["level"].Value) : 0);
			}
			this._isCastle = (node.Attributes["is_castle"] != null && bool.Parse(node.Attributes["is_castle"].Value));
			base.BackgroundCropPosition = float.Parse(node.Attributes["background_crop_position"].Value);
			base.BackgroundMeshName = node.Attributes["background_mesh"].Value;
			base.WaitMeshName = node.Attributes["wait_mesh"].Value;
			if (!base.IsInitialized)
			{
				this._prosperity = float.Parse(node.Attributes["prosperity"].Value);
			}
			this.BesiegerCampPositions1 = new MatrixFrame[]
			{
				MatrixFrame.Identity
			};
			this.BesiegerCampPositions2 = new MatrixFrame[]
			{
				MatrixFrame.Identity
			};
			base.Deserialize(objectManager, node);
		}

		// Token: 0x06003247 RID: 12871 RVA: 0x000D25BD File Offset: 0x000D07BD
		public void SetSoldItems(IEnumerable<Town.SellLog> logList)
		{
			this._soldItems = logList.ToArray<Town.SellLog>();
		}

		// Token: 0x06003248 RID: 12872 RVA: 0x000D25CB File Offset: 0x000D07CB
		public override int GetItemPrice(ItemObject item, MobileParty tradingParty = null, bool isSelling = false)
		{
			return this.MarketData.GetPrice(item, tradingParty, isSelling, null);
		}

		// Token: 0x06003249 RID: 12873 RVA: 0x000D25DC File Offset: 0x000D07DC
		public override int GetItemPrice(EquipmentElement itemRosterElement, MobileParty tradingParty = null, bool isSelling = false)
		{
			return this.MarketData.GetPrice(itemRosterElement, tradingParty, isSelling, null);
		}

		// Token: 0x0600324A RID: 12874 RVA: 0x000D25ED File Offset: 0x000D07ED
		public override SettlementComponent.ProsperityLevel GetProsperityLevel()
		{
			if (this._prosperity >= 5000f)
			{
				return SettlementComponent.ProsperityLevel.High;
			}
			if (this._prosperity >= 2000f)
			{
				return SettlementComponent.ProsperityLevel.Mid;
			}
			return SettlementComponent.ProsperityLevel.Low;
		}

		// Token: 0x0600324B RID: 12875 RVA: 0x000D2610 File Offset: 0x000D0810
		private void TickCurrentBuilding()
		{
			if (this.BuildingsInProgress.Peek().CurrentLevel == 3)
			{
				this.BuildingsInProgress.Dequeue();
			}
			if (!base.Owner.Settlement.IsUnderSiege && !this.BuildingsInProgress.IsEmpty<Building>())
			{
				BuildingConstructionModel buildingConstructionModel = Campaign.Current.Models.BuildingConstructionModel;
				Building building = this.BuildingsInProgress.Peek();
				building.BuildingProgress += this.Construction;
				int num = this.IsCastle ? buildingConstructionModel.CastleBoostCost : buildingConstructionModel.TownBoostCost;
				if (this.BoostBuildingProcess > 0)
				{
					this.BoostBuildingProcess -= num;
					if (this.BoostBuildingProcess < 0)
					{
						this.BoostBuildingProcess = 0;
					}
				}
				if ((float)building.GetConstructionCost() <= building.BuildingProgress)
				{
					if (building.CurrentLevel < 3)
					{
						building.LevelUp();
					}
					if (building.CurrentLevel == 3)
					{
						building.BuildingProgress = (float)building.GetConstructionCost();
					}
					this.BuildingsInProgress.Dequeue();
				}
			}
		}

		// Token: 0x0600324C RID: 12876 RVA: 0x000D270E File Offset: 0x000D090E
		protected override void OnInventoryUpdated(ItemRosterElement item, int count)
		{
			this.MarketData.OnTownInventoryUpdated(item, count);
		}

		// Token: 0x0600324D RID: 12877 RVA: 0x000D271D File Offset: 0x000D091D
		public float GetItemCategoryPriceIndex(ItemCategory itemCategory)
		{
			return this.MarketData.GetPriceFactor(itemCategory);
		}

		// Token: 0x04001027 RID: 4135
		private const int InitialTownGold = 20000;

		// Token: 0x04001028 RID: 4136
		private const int HighProsperityThreshold = 5000;

		// Token: 0x04001029 RID: 4137
		private const int MidProsperityThreshold = 2000;

		// Token: 0x0400102A RID: 4138
		[SaveableField(1017)]
		private float _prosperity;

		// Token: 0x0400102B RID: 4139
		[CachedData]
		public MatrixFrame[] BesiegerCampPositions1;

		// Token: 0x0400102C RID: 4140
		[CachedData]
		public MatrixFrame[] BesiegerCampPositions2;

		// Token: 0x0400102D RID: 4141
		[SaveableField(1000)]
		private int _wallLevel;

		// Token: 0x0400102E RID: 4142
		private bool _isCastle;

		// Token: 0x0400102F RID: 4143
		[SaveableField(1016)]
		public bool GarrisonAutoRecruitmentIsEnabled = true;

		// Token: 0x04001030 RID: 4144
		[SaveableField(1040)]
		private Clan _ownerClan;

		// Token: 0x04001031 RID: 4145
		[SaveableField(1015)]
		private float _security;

		// Token: 0x04001032 RID: 4146
		[SaveableField(1014)]
		private float _loyalty;

		// Token: 0x04001033 RID: 4147
		[CachedData]
		private MBList<Village> _tradeBoundVillagesCache;

		// Token: 0x04001035 RID: 4149
		[SaveableField(1006)]
		public MBList<Building> Buildings;

		// Token: 0x04001036 RID: 4150
		[SaveableField(1007)]
		public Queue<Building> BuildingsInProgress;

		// Token: 0x04001037 RID: 4151
		[SaveableField(1008)]
		public int BoostBuildingProcess;

		// Token: 0x04001038 RID: 4152
		[SaveableField(1009)]
		private readonly TownMarketData _marketData;

		// Token: 0x04001039 RID: 4153
		[SaveableField(1010)]
		private int _tradeTax;

		// Token: 0x0400103A RID: 4154
		[SaveableField(1011)]
		public bool InRebelliousState;

		// Token: 0x0400103B RID: 4155
		[SaveableField(1012)]
		private Hero _governor;

		// Token: 0x0400103C RID: 4156
		[SaveableField(1013)]
		private Town.SellLog[] _soldItems = new Town.SellLog[0];

		// Token: 0x020006A1 RID: 1697
		public struct SellLog
		{
			// Token: 0x0600563C RID: 22076 RVA: 0x0017EA80 File Offset: 0x0017CC80
			public static void AutoGeneratedStaticCollectObjectsSellLog(object o, List<object> collectedObjects)
			{
				((Town.SellLog)o).AutoGeneratedInstanceCollectObjects(collectedObjects);
			}

			// Token: 0x0600563D RID: 22077 RVA: 0x0017EA9C File Offset: 0x0017CC9C
			private void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
			{
				collectedObjects.Add(this.Category);
			}

			// Token: 0x0600563E RID: 22078 RVA: 0x0017EAAC File Offset: 0x0017CCAC
			internal static object AutoGeneratedGetMemberValueCategory(object o)
			{
				return ((Town.SellLog)o).Category;
			}

			// Token: 0x0600563F RID: 22079 RVA: 0x0017EAC8 File Offset: 0x0017CCC8
			internal static object AutoGeneratedGetMemberValueNumber(object o)
			{
				return ((Town.SellLog)o).Number;
			}

			// Token: 0x17001395 RID: 5013
			// (get) Token: 0x06005640 RID: 22080 RVA: 0x0017EAE8 File Offset: 0x0017CCE8
			// (set) Token: 0x06005641 RID: 22081 RVA: 0x0017EAF0 File Offset: 0x0017CCF0
			[SaveableProperty(200)]
			public ItemCategory Category { get; private set; }

			// Token: 0x17001396 RID: 5014
			// (get) Token: 0x06005642 RID: 22082 RVA: 0x0017EAF9 File Offset: 0x0017CCF9
			// (set) Token: 0x06005643 RID: 22083 RVA: 0x0017EB01 File Offset: 0x0017CD01
			[SaveableProperty(201)]
			public int Number { get; private set; }

			// Token: 0x06005644 RID: 22084 RVA: 0x0017EB0A File Offset: 0x0017CD0A
			public SellLog(ItemCategory category, int count)
			{
				this.Category = category;
				this.Number = count;
			}
		}
	}
}
